using System;
using System.Web.Mvc;
using ETestIT.Web.Controllers;
using Microsoft.Web.Mvc;

namespace ETestIT.Web.Presentation
{
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Web.UI;
    using Castle.Core;
    using Core;
    using TR3V.Web.HtmlControls;

    public static class PositionExtensions
    {
        private const string PositionAnJobTitle = @"<div class=""portlet""><div class=""portlet-content"">{0}</div></div>";
        private const string BlankPosition = @"<div class=""portlet""><div class=""portlet-content"">&nbsp;</div></div>";
        private const string PositionFormat = @"<div class=""portlet"">
		                                            <div class=""portlet-header"">{0}</div>
		                                            <div class=""portlet-content"">{1}</div>
	                                            </div>";

        public static string ShowAsDashBoard(this HtmlHelper helper, IEnumerable<Position> positions)
        {

            if (positions.Count() == 0)
                return string.Empty;

            var distinctCompanies = GetDistinctCompanies(positions);
            var distinctTitles = GetDistinctJobTitles(positions);
            var positionsMatrix = GetCompanyTitlesMatrix(positions);

            using (var table = new TableBuilder())
            {
                table.CssClass = "dashboard";
                table.AddHeaderRow(PrepareTableHeaders(helper, distinctTitles));

                distinctCompanies.ForEach(
                    client => table.AddRow(PrepareTableRow(helper, distinctTitles, client, positionsMatrix)));

                return RenderTableBuilder(table);
            }
        }

        private static string[] PrepareTableRow(
            HtmlHelper helper,
            IEnumerable<JobTitle> distinctTitles, 
            Client client, 
            IDictionary<string, List<Position>> positionsMatrix)
        {
            var rowValues = new List<string> { string.Format(PositionAnJobTitle, client.Name) };

            foreach (var title in distinctTitles)
            {
                var positionCellKey = MakeCellKey(client, title);

                var result = BlankPosition;

                if (positionsMatrix.ContainsKey(positionCellKey))
                    positionsMatrix[positionCellKey].ForEach(x => { result = FormatPortlet(helper, x); });

                rowValues.Add(result);
            }
            return rowValues.ToArray();
        }

        private static string FormatPortlet(HtmlHelper helper, Position position)
        {
            string header = string.Empty;

            if (position.IsStar)
                header += helper.Image("content/images/Star.ico");
            
            if (position.ExcelentCommunicationSkills)
                header += helper.Image("content/images/Smiley.ico");
            
            if (position.IsRemote)
                header += helper.Image("content/images/Home.ico");

            header += string.Format(@"<a href=""#"" class=""opener"" position ='{0}'><img src='content/images/view.ico'></a>", position.Id);
            header += helper.ActionImage<PositionsController>(z => z.Edit(position.Id), "content/images/Edit.ico", "");

            var formId = Guid.NewGuid().ToString();
            header += string.Format("<form id='{0}' action='{1}' method='post' style='display:inline'>{2}{3}</form>",
                  formId,
                  helper.BuildUrlFromExpression<PositionsController>(z => z.Delete(position.Id)),
                  "<a href=# onclick=\"ConfirmeDialog('" + formId + "'); return false;\"><img src='content/images/delete.ico'></a>",
                  helper.AntiForgeryToken());

            var body =  "C:" + position.ThePosition +
                        ", D:" + position.Duration  +
                        ", O:" + position.Openings +
                        ", L:" + position.Location +
                        ", S:" + position.KeySkills.Substring(0, position.KeySkills.Length > 30 ? 30 : position.KeySkills.Length) + "...";

            return string.Format(PositionFormat, header, body) + HidenPopupData(position);
        }

        private static string HidenPopupData(Position position)
        {
            return @"<div id=""@pid"" title=""@company - @title"" style=""display:none"">
                                    <p><b>Title:</b> @title</p>
                                    <p><b>Company:</b> @company</p>
                                    <p><b>Position Type:</b> @contractType</p>
                                    <p><b>Duration:</b> @duration mths</p>
                                    <p><b>Location:</b> @location</p>
                                    <p><b>Key skills:</b> @keySkills</p>
                                    <p><b>Full description:</b> 
                                        @description
                                    </p>
                                </div>"
                .Replace("@pid", position.Id.ToString())
                .Replace("@company", position.TheComapny.Name)
                .Replace("@title", position.TheJobTitle.Name)
                .Replace("@contractType", position.ThePosition.ToString())
                .Replace("@duration", position.Duration.ToString())
                .Replace("@location", position.Location)
                .Replace("@keySkills", position.KeySkills)
                .Replace("@description", position.Description);
        }

        private static string RenderTableBuilder(TableBuilder tableBuilder)
        {
            var sb = new StringBuilder();
            var sw = new StringWriter(sb);
            var htw = new HtmlTextWriter(sw);

            tableBuilder.Table.RenderControl(htw);

            return sb.ToString();
        }

        private static string[] PrepareTableHeaders(HtmlHelper htmlHelper ,IEnumerable<JobTitle> distinctTitles)
        {
            var titles = new List<string>((from o in distinctTitles select string.Format(PositionAnJobTitle, o.Name)));
            titles.Insert(0, " ");
            
            return titles.ToArray();
        }

        private static string MakeCellKey(Client client, JobTitle title)
        {
            return client.Name + "_" + title.Name;
        }

        private static IEnumerable<JobTitle> GetDistinctJobTitles(IEnumerable<Position> positions)
        {
            return (from o in positions select o.TheJobTitle).Distinct();
        }

        private static IEnumerable<Client> GetDistinctCompanies(IEnumerable<Position> positions)
        {
            return (from o in positions select o.TheComapny).Distinct();
        }

        private static Dictionary<string, List<Position>> GetCompanyTitlesMatrix(IEnumerable<Position> positions)
        {
            var positionsMatrix = new Dictionary<string, List<Position>>();

            positions.ForEach(x =>
            {
                var cellKey = MakeCellKey(x.TheComapny, x.TheJobTitle);

                if (!positionsMatrix.ContainsKey(cellKey))
                    positionsMatrix[cellKey] = new List<Position>();

                positionsMatrix[cellKey].Add(x);
            });

            return positionsMatrix;
        }
    }
}